<?php

require_once(WSB_MODULES_PATH . 'media/Callback.php');
require_once(WSB_MODULES_PATH . 'media/Filesystem.php');
require_once(WSB_MODULES_PATH . 'media/Url.php');

class Media_FileController extends Zend_Controller_Action
{
	protected $_filter = '';

	public function init()
	{
		parent::init(); // immer zuerst!

		// TABs nicht in Popups darstellen
		if(!in_array($this->_request->getActionName(), array('browser', 'fckeditor'))) {
			$navigation = $this->_helper->getHelper('Navigation');
			$navigation->add(Media_Url::fileListUrl(), 'Dateien');
			$navigation->add(Media_Url::uploadListUrl(), 'Upload');
		}

		$session = $this->getHelper('Session');
		$reset = $this->_request->get('reset');
		if(isset($reset)) {
			//$session->unsetAll();
			// Alle ausser "folder" loeschen
			unset($session->opener);
			unset($session->filter);
			unset($session->cut);
		}
		if($this->_request->get('filter') != '') {
			$session->filter = $this->_request->get('filter');
		}
		// Opener
		if($this->_request->get('opener') != '') {
			$session->opener = $this->_request->get('opener');
		}
		if(!empty($session->opener)) {
			$this->view->opener = $session->opener;
		}
		if(!empty($session->filter)) {
			$this->_filter = $session->filter;
		}
		$this->view->filter = $this->_filter;
	}

	public function browserAction()
	{

		$path = $this->_getRequestedPath();

		try {

			$session = $this->getHelper('Session');

			$dirIterator = new WSB_DirectoryIterator($path);

	    	$this->view->dirIterator = $dirIterator;
			$this->view->breadcrumb = Media_Filesystem::buildBreadcrumb($dirIterator->getRelativePath());

	    	// Settings fuer htmlTable-Viewhelper
			$this->view->columns = array(
				array('key' => 'icons', 'label' => '', 'sortable' => 'true'),
				array('key' => 'name', 'label' => 'Name', 'sortable' => 'true', 'width' => '90%'),
				array('key' => 'perm', 'label' => 'Perm', 'sortable' => 'true'),
				array('key' => 'type', 'label' => 'Type', 'sortable' => 'true'),
				array('key' => 'size', 'label' => 'Size', 'sortable' => 'true'),
				array('key' => 'links', 'label' => '', 'text-align' => 'right')
			);

			$this->view->fields = array(
				array('key' => 'icons', 'callback' => array('Media_Callback', 'icon')),
				array('key' => 'name', 'callback' => array('Media_Callback', 'browserName')),
				array('key' => 'perm', 'callback' => array('Media_Callback', 'perm')),
				array('key' => 'type', 'callback' => array('Media_Callback', 'type')),
				array('key' => 'size', 'callback' => array('Media_Callback', 'size')),
				array('key' => 'links', 'callback' => array('Media_Callback', 'browserLinks'))
			);

			$this->view->settings = array(
				'sortedBy' => array(
					'key' => 'type', 'dir' => 'asc'
				),
				'callback' => array('Media_Callback', 'browserValid')
			);

			if($dirIterator->isEmpty()) {
				$this->render('empty');
			} else {
				$this->render();
			}

		} catch (Exception $e) {
			$this->render('error');
		}

	}

	public function fckeditorAction()
	{

		$path = $this->_getRequestedPath();

		try {

			$session = $this->getHelper('Session');

			$dirIterator = new WSB_DirectoryIterator($path);

	    	$this->view->dirIterator = $dirIterator;
			$this->view->breadcrumb = Media_Filesystem::buildBreadcrumb($dirIterator->getRelativePath());

	    	// Settings fuer htmlTable-Viewhelper
			$this->view->columns = array(
				array('key' => 'icons', 'label' => '', 'sortable' => 'true'),
				array('key' => 'name', 'label' => 'Name', 'sortable' => 'true', 'width' => '90%'),
				array('key' => 'perm', 'label' => 'Perm', 'sortable' => 'true'),
				array('key' => 'type', 'label' => 'Type', 'sortable' => 'true'),
				array('key' => 'size', 'label' => 'Size', 'sortable' => 'true'),
				array('key' => 'links', 'label' => '', 'text-align' => 'right')
			);

			$this->view->fields = array(
				array('key' => 'icons', 'callback' => array('Media_Callback', 'icon')),
				array('key' => 'name', 'callback' => array('Media_Callback', 'fckeditorName')),
				array('key' => 'perm', 'callback' => array('Media_Callback', 'perm')),
				array('key' => 'type', 'callback' => array('Media_Callback', 'type')),
				array('key' => 'size', 'callback' => array('Media_Callback', 'size')),
				array('key' => 'links', 'callback' => array('Media_Callback', 'fckeditorLinks'))
			);

			$this->view->settings = array(
				'sortedBy' => array(
					'key' => 'type', 'dir' => 'asc'
				),
				'callback' => array('Media_Callback', 'fckeditorValid')
			);

			if($dirIterator->isEmpty()) {
				$this->render('empty');
			} else {
				$this->render();
			}

		} catch (Exception $e) {
			$this->render('error');
		}

	}

	public function indexAction()
	{
		$path = $this->_getRequestedPath();

		try {

			$session = $this->getHelper('Session');

			$dirIterator = new WSB_DirectoryIterator($path);

	    	$this->view->dirIterator = $dirIterator;
			$this->view->breadcrumb = Media_Filesystem::buildBreadcrumb($dirIterator->getRelativePath());

	    	// Settings fuer htmlTable-Viewhelper
			$this->view->columns = array(
				array('key' => 'icons', 'label' => '', 'sortable' => 'true'),
				array('key' => 'name', 'label' => 'Name', 'sortable' => 'true', 'width' => '90%'),
				array('key' => 'perm', 'label' => 'Perm', 'sortable' => 'true'),
				array('key' => 'type', 'label' => 'Type', 'sortable' => 'true'),
				array('key' => 'size', 'label' => 'Size', 'sortable' => 'true'),
				array('key' => 'links', 'label' => '', 'text-align' => 'right')
			);

			$this->view->fields = array(
				array('key' => 'icons', 'callback' => array('Media_Callback', 'icon')),
				array('key' => 'name', 'callback' => array('Media_Callback', 'name')),
				array('key' => 'perm', 'callback' => array('Media_Callback', 'perm')),
				array('key' => 'type', 'callback' => array('Media_Callback', 'type')),
				array('key' => 'size', 'callback' => array('Media_Callback', 'size')),
				array('key' => 'links', 'callback' => array('Media_Callback', 'links'))
			);

			$this->view->settings = array(
				'sortedBy' => array(
					'key' => 'type', 'dir' => 'asc'
				),
				'callback' => array('Media_Callback', 'valid')
			);

			if($dirIterator->isEmpty()) {
				$this->render('empty');
			} else {
				$this->render();
			}

		} catch (Exception $e) {
			$this->render('error');
		}

		$this->_renderFolderTree();

	}

	public function cutAction()
	{
    	$file = $this->_request->getQuery('cut');
    	if(!empty($file)) {
    		$session = $this->getHelper('Session');
			$session->cut = $file;
    	}
		$this->_forward('index');
	}

	public function pasteAction()
	{
    	$session = $this->getHelper('Session');
		if(!empty($session->cut)) {

			$mediaPath = Media_Filesystem::getMediaFolderPath();
			$fileToCut = $mediaPath . '/' . $session->cut;
			$fileToPaste = $mediaPath . '/' . $this->_request->getQuery('paste') . '/' . basename($session->cut);

    		if($fileToCut != $fileToPaste) {
	    		if(is_file($fileToCut)) {
	    			if(!file_exists($fileToPaste)) {
	    				if(copy($fileToCut, $fileToPaste)) {
	    					$config = Zend_Registry::get('Zend_Config');
							$relCut = $config->file->filePath . $session->cut;
							$relPaste = $config->file->filePath . $this->_request->getQuery('paste') . '/' . basename($session->cut);
							$relPaste = str_replace('//', '/', $relPaste);
							$this->_cutPasteInDb($relCut, $relPaste);
							unlink($fileToCut);
	    				}
	    			}
	    		}
    		}
	    	unset($session->cut);
		}
		$this->_forward('index');
	}

	private function _cutPasteInDb($fileToCut, $fileToPaste)
	{
		$config = Zend_Registry::get('Zend_Config');
		$prefix = $config->file->filePath;
		$prefixLength = strlen($prefix);
		if(substr($fileToCut, 0, $prefixLength) == $prefix) {
			if(substr($fileToPaste, 0, $prefixLength) == $prefix) {
				$db = Zend_Db_Table_Abstract::getDefaultAdapter();
				foreach($db->listTables() AS $table) {
					$info = $this->_replaceInTable($table, $fileToCut, $fileToPaste);
				}
			}
		}
	}

	/**
	 * Do a REPLACE statement over a whole table (with LIKE in the where clause).
	 * The $from and the $to string may not be empty!
	 * Return the number of affected rows.
	 *
	 * @param string $table
	 * @param string $from
	 * @param string $to
	 */
	private function _replaceInTable($table, $from, $to)
	{
		if(is_string($from) && !empty($from) && is_string($to) && !empty($to)) {
			$db = Zend_Db_Table_Abstract::getDefaultAdapter();
			$columns = $db->describeTable($table);
			if(is_array($columns) && (count($columns) > 0)) {

				$hasTextColumns = false;

				// SQL Anweisung
				$sql = "UPDATE `$table`";
				$sql .= " SET";
				// SET-Statement
				$delim = '';
				foreach($columns AS $column) {
					if($this->_isTextColumn($column)) {
						$sql .= $delim . '`' . $column['COLUMN_NAME'] . "` = REPLACE(`" . $column['COLUMN_NAME'] . "`, '" . $from . "', '" . $to . "')";
						$delim = ', ';
						$hasTextColumns = true;
					}
				}
				// WHERE-Klausel
				$i = 0;
				foreach($columns AS $column) {
					if($this->_isTextColumn($column)) {
						if($i == 0) {
							$sql .= ' WHERE ';
						} else {
							$sql .= ' OR ';
						}
						$sql .= '`' . $column['COLUMN_NAME'] . "` LIKE '%" . $from . "%'";
						$i++;
					}
				}
				if($hasTextColumns) {
					$db->query($sql);
				}
			}
		}
	}

	private function _isTextColumn(array $column)
	{
		$notTextTypes = array('int', 'tinyint', 'timestamp', 'datetime');
		if(in_array($column['DATA_TYPE'], $notTextTypes)) {
			return false;
		}
		return true;
	}

    public function deleteAction()
	{
    	/*
    	$file = $this->_request->getQuery('file');
    	$text = sprintf($this->_helper->Translate('delete.confirmation'), $file);
		$answer = WSB_Dialog::ConfirmDialog($text);
		if($answer == WSB_Dialog::YES_OPTION) {

			$fs = new Media_Filesystem();
			$fs->moveToTrash($file);

			WSB_Log::info(sprintf('Moved file %s to trash', $file));

			$this->_helper->FlashMessenger->addMessage(sprintf($this->_helper->Translate('delete.successfully'), $file));
		}
		$this->_forward('index');
		*/
    	$file = $this->_request->getQuery('file');
		$fs = new Media_Filesystem();
		$fs->moveToTrash($file);
		WSB_Log::info(sprintf('Moved file %s to trash', $file));
		$this->_helper->FlashMessenger->addMessage(sprintf($this->_helper->Translate('delete.successfully'), $file));
		//$this->_forward('index');
		$this->_helper->Redirect(Media_Url::fileListUrl());
    }

	private function _renderFolderTree()
	{
		$path = Media_Filesystem::getMediaFolderPath();
		$tree = new WSB_Dhtml_FolderTree($path);
		$tree->setPath($this->_getRequestedPath());

		$this->view->folderTree = $tree;
		$this->render('folder-tree', 'left');
	}

	protected function _getRequestedPath()
	{
		$request = $this->getRequest();
		$path = Media_Filesystem::getMediaFolderPath();
		$folder = $request->get('folder', '');

		// Auf Null pruefen (dies ist nur der Fall, wenn das Modul ohne
		// Parameter aufgerufen wird).
		// Falls kein Parameter uebergeben wird, hole den Pfad aus der Session,
		// aber nur, wenn ein gueltiger Pfad in der Session gespeichert ist.

		// $session = $this->getHelper('Session');
		// Gleicher Session Namespace im Module Media
		$session = new Zend_Session_Namespace('MediaModule');
		if(is_null($folder) && isset($session->path) && (is_dir($session->path))) {
			return $session->path;
		} else {
			$folder = Media_Filesystem::sanitizePath($folder);
			if($folder != '') {
				$path .= '/' . $folder;
			}
			$session->path = $path;
			return $path;
		}

	}

	public function createfolderAction()
	{
		$request = $this->getRequest();
		$folder = $request->getPost('folder');
		$dirname = $request->getPost('dirname');
		if(preg_match('/^[^\/\\\\":*?<>|]+$/', $dirname)) {
			$dirname = Media_Filesystem::filterDirname($dirname);
			$newDir = $this->_getRequestedPath() . '/' . $dirname;
			if(!is_dir($newDir)) {
				$config = Zend_Registry::get('Zend_Config');
				$mode = $config->file->folderCreateMask;
				umask(0);
				mkdir($newDir, $mode);
				WSB_Log::info(sprintf('Created folder %s', $folder . '/' . $dirname));
			}
		}
		$url = Media_Url::fileListUrl($folder);
		$this->_helper->Redirect($url);
	}

	public function uploadAction()
	{
		$request = $this->getRequest();
		if(key_exists('file', $_FILES)) {
			$config = Zend_Registry::get('Zend_Config');
			$fileInput = $_FILES['file'];
			if(intval($fileInput['size']) > 0) {
				$filteredFileName = Media_Filesystem::filterFilename($fileInput['name']);
				$dstFile = $this->_getRequestedPath() . '/' . $filteredFileName;
				if(!is_file($dstFile)) {
					move_uploaded_file($fileInput['tmp_name'], $dstFile);
					umask(0);
					chmod($dstFile, $config->file->fileCreateMask);
					WSB_Log::info(sprintf('Uploaded file %s', $filteredFileName));
				}
			}
		}
		$url = Media_Url::fileListUrl($request->getPost('folder'));
		$this->_helper->Redirect($url);
	}

}
